#ifndef MIPS_H
#define MIPS_H

#include "common.h"
#include "InterCode.h"

/* Registers of MIPS  */
#define REG_TPR 8 //Temporaries, $8~$15, saved by caller.

/* Address Descriptor */
typedef struct VarDes_
{
	char *name;			  //Name of variable.
	int regNo;			  //Number of register.
	int offset;			  //Address of variable in the memory.(relative to $fp栈底)
	struct VarDes_ *next; //Pointer to next variable.
} VarDes_;

/* Register Descriptor */
typedef struct RegDes_
{
	char *name;   //Name of register, TODO: can be replaced by No.?
	VarDes_ *var; //variable pointing to the current register.
} RegDes_;

/*----- External Data -----*/
extern VarDes_ *varList;
extern RegDes_ regs[];
extern char *regsAlias[];
extern int offset_sp;
extern int reg_cur;
extern int param_cur;
extern int arg_cur;
extern const int stackSize;

/* Functions Declaration */
void printMips(char *fileName);
void printMipsBlock(InterCode interCode, char *fileName);
void labelHandle(InterCode interCode, char *fileName);
void functionHandle(InterCode interCode, char *fileName);
void assignHandle(InterCode interCode, char *fileName);
void operationHandle(InterCode interCode, char *fileName);
void addressHandle(InterCode interCode, char *fileName);
void gotoHandle(InterCode interCode, char *fileName);
void ifgotoHandle(InterCode interCode, char *fileName);
void returnHandle(InterCode interCode, char *fileName);
void decHandle(InterCode interCode, char *fileName);
void argHandle(InterCode interCode, char *fileName);
void callHandle(InterCode interCode, char *fileName);
void paramHandle(InterCode interCode, char *fileName);
void readHandle(InterCode interCode, char *fileName);
void writeHandle(InterCode interCode, char *fileName);

void addVar(VarDes_ *var);
VarDes_ *locateVar(char *name);
void freeVarList();

void swReg(int index, FILE *fp);
void lwReg(int index, VarDes_ *var, FILE *fp);
void initRegs();
int allocateReg(Operand item, FILE *fp);

#endif
